/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved.
 * LP_SUBSYS module of 1711, Copyright (c) 2023-, Huawei
 *
 *
 *
 * This code is licensed under the GNU GPLv2 and later.
 */

#include "qemu/osdep.h"
#include "hw/qdev-properties.h"
#include "sysemu/runstate.h"
#include "hw/sysbus.h"
#include "migration/vmstate.h"
#include "qemu/log.h"
#include "qemu/module.h"
#include "qemu/qemu-print.h"
#include "crypto/random.h"
#include "qapi/error.h"

/* 高位地址选择寄存器 */
#define LPSC_ADDR_SEL       0x0000
/* 软复位控制寄存器0， 模块软复位请求控制 */
#define LPSC_SRST_REQ0      0x0004
/* 软复位控制寄存器1， 模块软复位请求控制 */
#define LPSC_SRST_REQ1      0x0008
/* 软复位控制寄存器2， 模块软复位请求控制 */
#define LPSC_SRST_REQ2      0x000C
/* 外设时钟使能寄存器0 */
#define LPSC_CLKEN_CTRL0        0x0010
/* 外设时钟使能寄存器1 */
#define LPSC_CLKEN_CTRL1        0x0014
/* crg时钟分频系数 */
#define LPSC_CRG_DIV_CTRL       0x0018
/* SPI控制 */
#define LPSC_SPI_CTRL       0x001C
/* gmac点灯控制，mdio控制，sdio 时钟控制 */
#define LPSC_MDIO_SDIO_CTRL     0x0020
/* SUPERIO控制 */
#define LPSC_SUPERIO_CTRL       0x0024
/* IO协处理器控制寄存器 */
#define LPSC_IOM3_CTRL      0x0028
/* uart内部互连选择控制 */
#define LPSC_UART_CTRL0     0x002C
/* uart内部互连选择控制 */
#define LPSC_UART_CTRL1     0x0030
/* UART互联端口使能控制 */
#define LPSC_UART_SEL       0x0034
/* eco寄存器 */
#define LPSC_ECO_NONUSE6        0x0038
/* PWM和GPIO的复位选择 */
#define LPSC_RESET_SEL      0x003C
/* 桥DBG寄存器0 */
#define LPSC_PERI_DBG_CTRL0     0x0040
/* 桥DBG寄存器1 */
#define LPSC_PERI_DBG_CTRL1     0x0044
/* 桥DBG状态寄存器 */
#define LPSC_PERI_DBG_CTRL2     0x0048
/* i2c0, 1挂死后恢复控制 */
#define LPSC_I2C_CTRL0      0x004C
/* i2c2, 3挂死后恢复控制 */
#define LPSC_I2C_CTRL1      0x0050
/* i2c4, 5挂死后恢复控制 */
#define LPSC_I2C_CTRL2      0x0054
/* i2c6, 7挂死后恢复控制 */
#define LPSC_I2C_CTRL3      0x0058
/* i2c8, 9挂死后恢复控制 */
#define LPSC_I2C_CTRL4      0x005C
/* i2c10, 11挂死后恢复控制 */
#define LPSC_I2C_CTRL5      0x0060
/* i2c12, 13挂死后恢复控制 */
#define LPSC_I2C_CTRL6      0x0064
/* i2c14, 15挂死后恢复控制 */
#define LPSC_I2C_CTRL7      0x0068
/* DMAC的请求端口0，外设选择寄存器 */
#define LPSC_DMAC_REQ_SEL0      0x006C
/* DMAC的请求端口1，外设选择寄存器 */
#define LPSC_DMAC_REQ_SEL1      0x0070
/* DMAC的请求端口2，外设选择寄存器 */
#define LPSC_DMAC_REQ_SEL2      0x0074
/* DMAC的请求端口3，外设选择寄存器 */
#define LPSC_DMAC_REQ_SEL3      0x0078
/* DMAC的请求端口4，外设选择寄存器 */
#define LPSC_DMAC_REQ_SEL4      0x007C
/* DMAC的请求端口5，外设选择寄存器 */
#define LPSC_DMAC_REQ_SEL5      0x0080
/* DMAC的请求端口6，外设选择寄存器 */
#define LPSC_DMAC_REQ_SEL6      0x0084
/* DMAC的请求端口7，外设选择寄存器 */
#define LPSC_DMAC_REQ_SEL7      0x0088
/* DMAC的请求端口8，外设选择寄存器 */
#define LPSC_DMAC_REQ_SEL8      0x008C
/* DMAC的请求端口9，外设选择寄存器 */
#define LPSC_DMAC_REQ_SEL9      0x0090
/* DMAC的请求端口10，外设选择寄存器 */
#define LPSC_DMAC_REQ_SEL10      0x0094
/* DMAC的请求端口11，外设选择寄存器 */
#define LPSC_DMAC_REQ_SEL11      0x0098
/* DMAC的请求端口12，外设选择寄存器 */
#define LPSC_DMAC_REQ_SEL12      0x009C
/* DMAC的请求端口13，外设选择寄存器 */
#define LPSC_DMAC_REQ_SEL13      0x00A0
/* DMAC的请求端口14，外设选择寄存器 */
#define LPSC_DMAC_REQ_SEL14      0x00A4
/* DMAC的请求端口15，外设选择寄存器 */
#define LPSC_DMAC_REQ_SEL15      0x00A8
/* DMAC的请求端口16，外设选择寄存器 */
#define LPSC_DMAC_REQ_SEL16      0x00AC
/* DMAC的请求端口17，外设选择寄存器 */
#define LPSC_DMAC_REQ_SEL17      0x00B0
/* DMAC的请求端口18，外设选择寄存器 */
#define LPSC_DMAC_REQ_SEL18      0x00B4
/* DMAC的请求端口19，外设选择寄存器 */
#define LPSC_DMAC_REQ_SEL19      0x00B8
/* DMAC的请求端口20，外设选择寄存器 */
#define LPSC_DMAC_REQ_SEL20      0x00BC
/* DMAC的请求端口21，外设选择寄存器 */
#define LPSC_DMAC_REQ_SEL21      0x00C0
/* DMAC的请求端口22，外设选择寄存器 */
#define LPSC_DMAC_REQ_SEL22      0x00C4
/* DMAC的请求端口23，外设选择寄存器 */
#define LPSC_DMAC_REQ_SEL23      0x00C8
/* DMAC的请求端口24，外设选择寄存器 */
#define LPSC_DMAC_REQ_SEL24      0x00CC
/* DMAC的请求端口25，外设选择寄存器 */
#define LPSC_DMAC_REQ_SEL25      0x00D0
/* DMAC的请求端口26，外设选择寄存器 */
#define LPSC_DMAC_REQ_SEL26      0x00D4
/* DMAC的请求端口27，外设选择寄存器 */
#define LPSC_DMAC_REQ_SEL27      0x00D8
/* DMAC的请求端口28，外设选择寄存器 */
#define LPSC_DMAC_REQ_SEL28      0x00DC
/* DMAC的请求端口29，外设选择寄存器 */
#define LPSC_DMAC_REQ_SEL29      0x00E0
/* DMAC的请求端口30，外设选择寄存器 */
#define LPSC_DMAC_REQ_SEL30      0x00E4
/* DMAC的请求端口31，外设选择寄存器 */
#define LPSC_DMAC_REQ_SEL31      0x00E8
/* Ahb master的hprot信号 */
#define LPSC_AHB_MST_HPROT     0x00EC
/* EMMC FUNCTION控制寄存器 */
#define LPSC_EMMC_FUNC_CTRL     0x00F0
/* EMMC FUNCTION控制寄存器 */
#define LPSC_EMMC_FUNC_CTRL1     0x00F4
/* emmc 时钟软复位控制 */
#define LPSC_EMMC_CRG_CTRL      0x00F8
/* harden内桥低功耗控制 */
#define LPSC_LOW_POWER_CTRL    0x00FC
/* smbus和i2c功能选择 */
#define LPSC_SMBUS_I2C_MUX      0x0100
/* PWM的OEN寄存器 */
#define LPSC_PAD_PWM_OEN        0x0104
/* PWM的选择寄存器0 */
#define LPSC_PAD_PWM_SEL0       0x0108
/* PWM的选择寄存器1 */
#define LPSC_PAD_PWM_SEL1       0x010C
/* PWM的选择寄存器2 */
#define LPSC_PAD_PWM_SEL2       0x0110
/* PWM的选择寄存器3 */
#define LPSC_PAD_PWM_SEL3       0x0114
/* PWM的选择寄存器4 */
#define LPSC_PAD_PWM_SEL4       0x0118
/* PWM的选择寄存器5 */
#define LPSC_PAD_PWM_SEL5       0x011C
/* PWM的选择寄存器6 */
#define LPSC_PAD_PWM_SEL6       0x0120
/* PWM的选择寄存器7 */
#define LPSC_PAD_PWM_SEL7       0x0124
/* PWM的选择寄存器8 */
#define LPSC_PAD_PWM_SEL8       0x0128
/* PWM的选择寄存器9 */
#define LPSC_PAD_PWM_SEL9       0x012C
/* PWM的选择寄存器10 */
#define LPSC_PAD_PWM_SEL10       0x0130
/* PWM的选择寄存器11 */
#define LPSC_PAD_PWM_SEL11      0x0134
/* PWM的选择寄存器12 */
#define LPSC_PAD_PWM_SEL12       0x0138
/* PWM的选择寄存器13 */
#define LPSC_PAD_PWM_SEL13       0x013C
/* PWM的选择寄存器14 */
#define LPSC_PAD_PWM_SEL14       0x0140
/* PWM的选择寄存器15 */
#define LPSC_PAD_PWM_SEL15       0x0144
/* PWM的选择寄存器16 */
#define LPSC_PAD_PWM_SEL16       0x0148
/* PWM的选择寄存器17 */
#define LPSC_PAD_PWM_SEL17       0x014C
/* PWM的选择寄存器18 */
#define LPSC_PAD_PWM_SEL18       0x0150
/* PWM的选择寄存器19 */
#define LPSC_PAD_PWM_SEL19       0x0154
/* PWM的选择寄存器20 */
#define LPSC_PAD_PWM_SEL20       0x0158
/* PWM的选择寄存器21 */
#define LPSC_PAD_PWM_SEL21       0x015C
/* PWM的选择寄存器22 */
#define LPSC_PAD_PWM_SEL22       0x0160
/* PWM的选择寄存器23 */
#define LPSC_PAD_PWM_SEL23       0x0164
/* PWM的选择寄存器24 */
#define LPSC_PAD_PWM_SEL24       0x0168
/* PWM的选择寄存器25 */
#define LPSC_PAD_PWM_SEL25       0x016C
/* PWM的选择寄存器26 */
#define LPSC_PAD_PWM_SEL26       0x0170
/* PWM的选择寄存器27 */
#define LPSC_PAD_PWM_SEL27       0x0174
/* FAN的选择寄存器0 */
#define LPSC_PAD_FAN_SEL0       0x0178
/* FAN的选择寄存器1 */
#define LPSC_PAD_FAN_SEL1       0x017C
/* FAN的选择寄存器2 */
#define LPSC_PAD_FAN_SEL2       0x0180
/* FAN的选择寄存器3 */
#define LPSC_PAD_FAN_SEL3       0x0184
/* FAN的选择寄存器4 */
#define LPSC_PAD_FAN_SEL4       0x0188
/* FAN的选择寄存器5 */
#define LPSC_PAD_FAN_SEL5       0x018C
/* FAN的选择寄存器6 */
#define LPSC_PAD_FAN_SEL6       0x0190
/* FAN的选择寄存器7 */
#define LPSC_PAD_FAN_SEL7       0x0194
/* FAN的选择寄存器8 */
#define LPSC_PAD_FAN_SEL8       0x0198
/* FAN的选择寄存器9 */
#define LPSC_PAD_FAN_SEL9       0x019C
/* FAN的选择寄存器10 */
#define LPSC_PAD_FAN_SEL10       0x01A0
/* FAN的选择寄存器11 */
#define LPSC_PAD_FAN_SEL11       0x01A4
/* FAN的选择寄存器12 */
#define LPSC_PAD_FAN_SEL12       0x01A8
/* FAN的选择寄存器13 */
#define LPSC_PAD_FAN_SEL13       0x01AC
/* FAN的选择寄存器14 */
#define LPSC_PAD_FAN_SEL14       0x01B0
/* FAN的选择寄存器15 */
#define LPSC_PAD_FAN_SEL15       0x01B4
/* 外设时钟关闭寄存器0 */
#define LPSC_CLKDIS_CTRL0       0x01B8
/* 外设时钟状态寄存器0 */
#define LPSC_CLKSTA_CTRL0       0x01BC
/* 外设时钟关闭寄存器1 */
#define LPSC_CLKDIS_CTRL1       0x01C0
/* 外设时钟状态寄存器1 */
#define LPSC_CLKSTA_CTRL1       0x01C4
/* sol桥DBG寄存器0 */
#define LPSC_SOL_BRG_DBG_CTRL0      0x01C8
/* sol桥DBG寄存器1 */
#define LPSC_SOL_BRG_DBG_CTRL1      0x01CC
/* 桥DBG状态寄存器 */
#define LPSC_SOL_BRG_DBG_CTRL2      0x01D0
/* jlc memory 控制 */
#define LPSC_JLC_MEM_CTRL       0x01D4
/* sram memory 控制 */
#define LPSC_SRAM_MEM_CTRL      0x01D8
/* dmac memory 控制 */
#define LPSC_DMAC_MEM_CTRL      0x01DC
/* ipmb0 memory 控制 */
#define LPSC_IPMB0_MEM_CTRL     0x01E0
/* ipmb1 memory 控制 */
#define LPSC_IPMB1_MEM_CTRL     0x01E4
/* ipmb2 memory 控制 */
#define LPSC_IPMB2_MEM_CTRL     0x01E8
/* ipmb3 memory 控制 */
#define LPSC_IPMB3_MEM_CTRL     0x01EC
/* sfc0 memory 控制 */
#define LPSC_SFC0_MEM_CTRL      0x01F0
/* sfc1 memory 控制 */
#define LPSC_SFC1_MEM_CTRL      0x01F4
/* emmc memory 控制 */
#define LPSC_EMMC_MEM_CTRL      0x01F8
/* 软复位去请求控制寄存器0，模块软复位去请求控制 */
#define LPSC_RESET_DREQ0        0x01FC
/* 软复位去请求控制寄存器1，模块软复位去请求控制 */
#define LPSC_RESET_DREQ1        0x0200
/* 软复位去请求控制寄存器2，模块软复位去请求控制 */
#define LPSC_RESET_DREQ2        0x0204
/* 软复位状态寄存器0 */
#define LPSC_RESET_ST0      0x0208
/* 软复位状态寄存器1 */
#define LPSC_RESET_ST1      0x020C
/* 软复位状态寄存器2 */
#define LPSC_RESET_ST2      0x0210
/* LP内排空模块控制 */
#define LPSC_EMP_CTRL       0x0214
/* LP内排空模块状态 */
#define LPSC_EMP_ST     0x0218
/* sol桥DBG寄存器3 (无意义) */
#define LPSC_SOL_BRG_DBG_CTRL3      0x021C
/* sol桥DBG寄存器4 (无意义) */
#define LPSC_SOL_BRG_DBG_CTRL4      0x0220
/* 桥DBG状态寄存器5 (无意义) */
#define LPSC_SOL_BRG_DBG_CTRL5      0x0224
/* se_m3_3x1桥挂死寄存器（无意义） */
#define LPSC_SE_M3_3X1_DLOCK        0x0228
/* se_m3_3x1桥优先级配置寄存器 */
#define LPSC_SE_M3_3X1_PRIORITY     0x022C
/* se_dma_3x1桥挂死寄存器 */
#define LPSC_SE_DMA_3X1_DLOCK       0x0230
/* se_dma_3x1桥优先级配置寄存器 */
#define LPSC_SE_DMA_3X1_PRIORITY       0x0234
/* se_sec_4x6桥挂死寄存器 */
#define LPSC_SE_SEC_4X6_DLOCK       0x0238
/* se_sec_4x6桥优先级配置寄存器 */
#define LPSC_SE_SEC_4X6_PRIORITY       0x023C
/* se_sec_1x3桥挂死寄存器 */
#define LPSC_SE_SEC_1X3_DLOCK       0x0240
/* se_sec_1x3桥优先级配置寄存器 */
#define LPSC_SE_SEC_1X3_PRIORITY       0x0244
/* se_sec_1x6桥挂死寄存器 */
#define LPSC_SE_SEC_1X6_DLOCK       0x0248
/* se_sec_1x6桥优先级配置寄存器 */
#define LPSC_SE_SEC_1X6_PRIORITY       0x024C
/* lp_sol_2x1桥挂死寄存器 */
#define LPSC_LP_SOL_2X1_DLOCK       0x0250
/* lp_sol_2x1桥优先级配置寄存器 */
#define LPSC_LP_SOL_2X1_PRIORITY       0x0254
/* 地址扩展模块控制寄存器0 */
#define LPSC_ADDR_EXTEND0       0x0258
/* 地址扩展模块控制寄存器1 */
#define LPSC_ADDR_EXTEND1       0x025C
/* ADC控制寄存器 */
#define LPSC_ADC_CTRL       0x0260
/* SRAM初始化寄存器 */
#define LPSC_SRAM_INI       0x0264
/* 排空模块错误上报寄存器 */
#define LPSC_EMP10_ERR      0x0268
/* TIMER时钟分频系数 */
#define LPSC_TIMER_DIV      0x026C
/* WatchDog时钟分频系数 */
#define LPSC_WDG_DIV        0x0270
/* 为进行IDDq测试，强制关闭所有FRQ */
#define LPSC_TRNG_TST_FRO_IDDQ      0x0274
/* 输出FRO的使能信号 */
#define LPSC_TRNG_TST_FRO_CTRL_EN       0x0278
/* 选择输出的FRO */
#define LPSC_TRNG_TST_FRO_SELECT        0x027C
/* 使能选择的FRO */
#define LPSC_TRNG_TST_FRO_ENABLE        0x0280
/* 选择FRO的delay */
#define LPSC_TRNG_TST_DELAY        0x0284
/* 。 */
#define LPSC_TRNG_SP_RAM_TMOD       0x0288
/* 。 */
#define LPSC_TRNG_MEM_POWER_MODE       0x028C
/* trng状态机的状态 */
#define LPSC_TRNG_FSM_STATE     0x0290
/* trng的PPROC状态 */
#define LPSC_TRNG_PPROC_STATE       0x0294
/* 桥DBG寄存器0 */
#define LPSC_M3_BRG_DBG_CTRL0       0x0298
/* 桥DBG寄存器1 */
#define LPSC_M3_BRG_DBG_CTRL1       0x029C
/* 桥DBG状态寄存器 */
#define LPSC_M3_BRG_DBG_CTRL2       0x02A0
/* LP子系统性能统计配置寄存器 */
#define LPSC_SPEED_CNT_CFG      0x02A4
/* M3性能统计匹配地址配置寄存器 */
#define M3_SPEED_CNT_MATCH_CFG      0x02A8
/* 存储DMA性能统计匹配地址配置寄存器 */
#define STORAGE_DMA_SPEED_CNT_MATCH_CFG     0x02AC
/* DMAC性能统计匹配地址配置寄存器 */
#define DMAC_SPEED_CNT_MATCH_CFG        0x02B0
/* M3性能统计写通道匹配次数统计 */
#define M3_SPEED_CNT_AWMATCH_INC_CNT        0x02B4
/* M3性能统计读通道匹配次数统计 */
#define M3_SPEED_CNT_RMATCH_INC_CNT        0x02B8
/* M3性能统计写命令次数统计 */
#define M3_SPEED_CNT_AWCMD_INC_CNT        0x02BC
/* M3性能统计读命令次数统计 */
#define M3_SPEED_CNT_RCMD_INC_CNT        0x02C0
/* 存储DMA性能统计写通道匹配次数统计 */
#define STORAGE_DMA_SPEED_CNT_AWMATCH_INC_CNT       0x02C4
/* 存储DMA性能统计读通道匹配次数统计 */
#define STORAGE_DMA_SPEED_CNT_RMATCH_INC_CNT       0x02C8
/* 存储DMA性能统计写命令次数统计 */
#define STORAGE_DMA_SPEED_CNT_AWCMD_INC_CNT       0x02CC
/* 存储DMA性能统计读命令次数统计 */
#define STORAGE_DMA_SPEED_CNT_RCMD_INC_CNT       0x02D0
/* DMAC性能统计写通道匹配次数统计 */
#define DMAC_SPEED_CNT_AWMATCH_INC_CNT      0x02D4
/* DMAC性能统计读通道匹配次数统计 */
#define DMAC_SPEED_CNT_RMATCH_INC_CNT      0x02D8
/* DMAC性能统计写命令次数统计 */
#define DMAC_SPEED_CNT_AWCMD_INC_CNT      0x02DC
/* DMAC性能统计读命令次数统计 */
#define DMAC_SPEED_CNT_RCMD_INC_CNT      0x02E0
/* M3性能统计写通道数据高位 */
#define M3_SPEED_CNT_WDATA_CNT_H         0x02E4
/* M3性能统计写通道数据低位 */
#define M3_SPEED_CNT_WDATA_CNT_L         0x02E8
/* M3性能统计读通道数据高位 */
#define M3_SPEED_CNT_RDATA_CNT_H         0x02EC
/* M3性能统计读通道数据低位 */
#define M3_SPEED_CNT_RDATA_CNT_L         0x02F0
/* 存储DMA性能统计写通道数据高位 */
#define STORAGE_DMA_SPEED_CNT_WDATA_CNT_H       0x02F4
/* 存储DMA性能统计写通道数据低位 */
#define STORAGE_DMA_SPEED_CNT_WDATA_CNT_L       0x02F8
/* 存储DMA性能统计读通道数据高位 */
#define STORAGE_DMA_SPEED_CNT_RDATA_CNT_H       0x02FC
/* 存储DMA性能统计读通道数据低位 */
#define STORAGE_DMA_SPEED_CNT_RDATA_CNT_L       0x0300
/* DMAC性能统计写通道数据高位 */
#define DMAC_SPEED_CNT_WDATA_CNT_H      0x0304
/* DMAC性能统计写通道数据低位 */
#define DMAC_SPEED_CNT_WDATA_CNT_L      0x0308
/* DMAC性能统计读通道数据高位 */
#define DMAC_SPEED_CNT_RDATA_CNT_H      0x030C
/* DMAC性能统计读通道数据低位 */
#define DMAC_SPEED_CNT_RDATA_CNT_L      0x0310
/* LP子系统HPM控制寄存器 */
#define LPSC_HPM_CTRL       0x0314
/* LP子系统HPM状态寄存器 */
#define LPSC_HPM_STATUS     0x0318
/* A55 DJTAG MASTER状态寄存器 */
#define LPSC_DJTAG_MSTR     0x031C
/* ECC中断原始状态寄存器 */
#define LPSC_ECC_INT_RAW        0x0320
/* ECC中断屏蔽寄存器 */
#define LPSC_ECC_INT_MASK       0x0324
/* ECC注错寄存器 */
#define LPSC_ECC_INST       0x0328
/* JLC初始化寄存器 */
#define LPSC_JLC_RAM_INI        0x032C
/* M3启动地址配置 */
#define LPSC_M3_BOOT_ADDR       0x0330
/* LP子系统内部IO复用寄存器 */
#define LPSC_IOMUX_CTRL     0x0334
/* 外设时钟使能寄存器2 */
#define LPSC_CLKEN_CTRL2        0x0338
/* 外设时钟关闭寄存器2 */
#define LPSC_CLKDIS_CTRL2       0x033C
/* 外设时钟状态寄存器2 */
#define LPSC_CLKSTA_CTRL2       0x0340
/* i2c0 debug寄存器 */
#define LPSC_I2C0_DEBUG     0x0344
/* i2c1 debug寄存器 */
#define LPSC_I2C1_DEBUG     0x0348
/* i2c2 debug寄存器 */
#define LPSC_I2C2_DEBUG     0x034C
/* i2c3 debug寄存器 */
#define LPSC_I2C3_DEBUG     0x0350
/* i2c4 debug寄存器 */
#define LPSC_I2C4_DEBUG     0x0354
/* i2c5 debug寄存器 */
#define LPSC_I2C5_DEBUG     0x0358
/* i2c6 debug寄存器 */
#define LPSC_I2C6_DEBUG     0x035C
/* i2c7 debug寄存器 */
#define LPSC_I2C7_DEBUG     0x0360
/* i2c8 debug寄存器 */
#define LPSC_I2C8_DEBUG     0x0364
/* i2c9 debug寄存器 */
#define LPSC_I2C9_DEBUG     0x0368
/* i2c10 debug寄存器 */
#define LPSC_I2C10_DEBUG        0x036C
/* i2c11 debug寄存器 */
#define LPSC_I2C11_DEBUG        0x0370
/* i2c12 debug寄存器 */
#define LPSC_I2C12_DEBUG        0x0374
/* i2c13 debug寄存器 */
#define LPSC_I2C13_DEBUG        0x0378
/* i2c14 debug寄存器 */
#define LPSC_I2C14_DEBUG        0x037C
/* i2c15 debug寄存器 */
#define LPSC_I2C15_DEBUG        0x0380
/* 延迟控制寄存器 */
#define LPSC_LATENCY_CTRL       0x0384
/* hard rr使能 */
#define LPSC_HARD_RR_CTRL       0x0388
/* 延时测试状态寄存器 */
#define LP_SC_LATENCY_STS_0   0x038C
/* 延时测试状态寄存器 */
#define LP_SC_LATENCY_STS_1   0x0390
/* 延时测试状态寄存器 */
#define LP_SC_LATENCY_STS_2   0x0394
/* emmc dll控制状态查询 */
#define LPSC_EMMC_DLL_ST        0x0398
/* ECO寄存器0 */
#define LPSC_ECO_NONUSE0        0x039C
/* ECO寄存器1 */
#define LPSC_ECO_NONUSE1        0x03A0
/* ECO寄存器2 */
#define LPSC_ECO_NONUSE2        0x03A4
/* ECO寄存器3 */
#define LPSC_ECO_NONUSE3        0x03A8
/* ECO寄存器4 */
#define LPSC_ECO_NONUSE4        0x03AC
/* ECO寄存器5 */
#define LPSC_ECO_NONUSE5        0x03B0
/* pad中断有效电平控制 */
#define LPSC_PAD_INT_LEVEL      0x03B4
/* pad中断屏蔽位 */
#define LPSC_PAD_INT_MASK       0x03B8
/* 非安全sram回写使能 */
#define LPSC_SRAM_WR_BACK       0x03BC
/* lp复位域调整使能 */
#define LPSC_RST_FIX        0x03C0

#define LP_SUBSYS_REGION_SIZE 0x0400
#define LPSC_TRNG_BIT BIT(16)
#define TYPE_LP_SUBSYS "lp_subsys"
#define LP_SUBSYS(obj) \
    OBJECT_CHECK(lp_subsys_state, (obj), TYPE_LP_SUBSYS)

typedef struct {
    uint32_t lpsc_addr_sel;
    uint32_t lpsc_srst_req0;
    uint32_t lpsc_srst_req1;
    uint32_t lpsc_srst_req2;
    uint32_t lpsc_clken_ctrl0;
    uint32_t lpsc_clken_ctrl1;
    uint32_t lpsc_crg_div_ctrl;
    uint32_t lpsc_spi_ctrl;
    uint32_t lpsc_mdio_sdio_ctrl;
    uint32_t lpsc_superio_ctrl;
    uint32_t lpsc_iom3_ctrl;
    uint32_t lpsc_uart_ctrl0;
    uint32_t lpsc_uart_ctrl1;
    uint32_t lpsc_uart_sel;
    uint32_t lpsc_eco_nonuse6;
    uint32_t lpsc_reset_sel;
    uint32_t lpsc_peri_dbg_ctrl0;
    uint32_t lpsc_peri_dbg_ctrl1;
    uint32_t lpsc_peri_dbg_ctrl2;
    uint32_t lpsc_i2c_ctrl0;
    uint32_t lpsc_i2c_ctrl1;
    uint32_t lpsc_i2c_ctrl2;
    uint32_t lpsc_i2c_ctrl3;
    uint32_t lpsc_i2c_ctrl4;
    uint32_t lpsc_i2c_ctrl5;
    uint32_t lpsc_i2c_ctrl6;
    uint32_t lpsc_i2c_ctrl7;
    uint32_t lpsc_dmac_req_sel0;
    uint32_t lpsc_dmac_req_sel1;
    uint32_t lpsc_dmac_req_sel2;
    uint32_t lpsc_dmac_req_sel3;
    uint32_t lpsc_dmac_req_sel4;
    uint32_t lpsc_dmac_req_sel5;
    uint32_t lpsc_dmac_req_sel6;
    uint32_t lpsc_dmac_req_sel7;
    uint32_t lpsc_dmac_req_sel8;
    uint32_t lpsc_dmac_req_sel9;
    uint32_t lpsc_dmac_req_sel10;
    uint32_t lpsc_dmac_req_sel11;
    uint32_t lpsc_dmac_req_sel12;
    uint32_t lpsc_dmac_req_sel13;
    uint32_t lpsc_dmac_req_sel14;
    uint32_t lpsc_dmac_req_sel15;
    uint32_t lpsc_dmac_req_sel16;
    uint32_t lpsc_dmac_req_sel17;
    uint32_t lpsc_dmac_req_sel18;
    uint32_t lpsc_dmac_req_sel19;
    uint32_t lpsc_dmac_req_sel20;
    uint32_t lpsc_dmac_req_sel21;
    uint32_t lpsc_dmac_req_sel22;
    uint32_t lpsc_dmac_req_sel23;
    uint32_t lpsc_dmac_req_sel24;
    uint32_t lpsc_dmac_req_sel25;
    uint32_t lpsc_dmac_req_sel26;
    uint32_t lpsc_dmac_req_sel27;
    uint32_t lpsc_dmac_req_sel28;
    uint32_t lpsc_dmac_req_sel29;
    uint32_t lpsc_dmac_req_sel30;
    uint32_t lpsc_dmac_req_sel31;
    uint32_t lpsc_ahb_mst_hprot;
    uint32_t lpsc_emmc_func_ctrl;
    uint32_t lpsc_emmc_func_ctrl1;
    uint32_t lpsc_emmc_crg_ctrl;
    uint32_t lpsc_low_power_ctrl;
    uint32_t lpsc_smbus_i2c_mux;
    uint32_t lpsc_pad_pwm_oen;
    uint32_t lpsc_pad_pwm_sel0;
    uint32_t lpsc_pad_pwm_sel1;
    uint32_t lpsc_pad_pwm_sel2;
    uint32_t lpsc_pad_pwm_sel3;
    uint32_t lpsc_pad_pwm_sel4;
    uint32_t lpsc_pad_pwm_sel5;
    uint32_t lpsc_pad_pwm_sel6;
    uint32_t lpsc_pad_pwm_sel7;
    uint32_t lpsc_pad_pwm_sel8;
    uint32_t lpsc_pad_pwm_sel9;
    uint32_t lpsc_pad_pwm_sel10;
    uint32_t lpsc_pad_pwm_sel11;
    uint32_t lpsc_pad_pwm_sel12;
    uint32_t lpsc_pad_pwm_sel13;
    uint32_t lpsc_pad_pwm_sel14;
    uint32_t lpsc_pad_pwm_sel15;
    uint32_t lpsc_pad_pwm_sel16;
    uint32_t lpsc_pad_pwm_sel17;
    uint32_t lpsc_pad_pwm_sel18;
    uint32_t lpsc_pad_pwm_sel19;
    uint32_t lpsc_pad_pwm_sel20;
    uint32_t lpsc_pad_pwm_sel21;
    uint32_t lpsc_pad_pwm_sel22;
    uint32_t lpsc_pad_pwm_sel23;
    uint32_t lpsc_pad_pwm_sel24;
    uint32_t lpsc_pad_pwm_sel25;
    uint32_t lpsc_pad_pwm_sel26;
    uint32_t lpsc_pad_pwm_sel27;
    uint32_t lpsc_pad_fan_sel0;
    uint32_t lpsc_pad_fan_sel1;
    uint32_t lpsc_pad_fan_sel2;
    uint32_t lpsc_pad_fan_sel3;
    uint32_t lpsc_pad_fan_sel4;
    uint32_t lpsc_pad_fan_sel5;
    uint32_t lpsc_pad_fan_sel6;
    uint32_t lpsc_pad_fan_sel7;
    uint32_t lpsc_pad_fan_sel8;
    uint32_t lpsc_pad_fan_sel9;
    uint32_t lpsc_pad_fan_sel10;
    uint32_t lpsc_pad_fan_sel11;
    uint32_t lpsc_pad_fan_sel12;
    uint32_t lpsc_pad_fan_sel13;
    uint32_t lpsc_pad_fan_sel14;
    uint32_t lpsc_pad_fan_sel15;
    uint32_t lpsc_clkdis_ctrl0;
    uint32_t lpsc_clksta_ctrl0;
    uint32_t lpsc_clkdis_ctrl1;
    uint32_t lpsc_clksta_ctrl1;
    uint32_t lpsc_sol_brg_dbg_ctrl0;
    uint32_t lpsc_sol_brg_dbg_ctrl1;
    uint32_t lpsc_sol_brg_dbg_ctrl2;
    uint32_t lpsc_jlc_mem_ctrl;
    uint32_t lpsc_sram_mem_ctrl;
    uint32_t lpsc_dmac_mem_ctrl;
    uint32_t lpsc_ipmb0_mem_ctrl;
    uint32_t lpsc_ipmb1_mem_ctrl;
    uint32_t lpsc_ipmb2_mem_ctrl;
    uint32_t lpsc_ipmb3_mem_ctrl;
    uint32_t lpsc_sfc0_mem_ctrl;
    uint32_t lpsc_sfc1_mem_ctrl;
    uint32_t lpsc_emmc_mem_ctrl;
    uint32_t lpsc_reset_dreq0;
    uint32_t lpsc_reset_dreq1;
    uint32_t lpsc_reset_dreq2;
    uint32_t lpsc_reset_st0;
    uint32_t lpsc_reset_st1;
    uint32_t lpsc_reset_st2;
    uint32_t lpsc_emp_ctrl;
    uint32_t lpsc_emp_st;
    uint32_t lpsc_sol_brg_dbg_ctrl3;
    uint32_t lpsc_sol_brg_dbg_ctrl4;
    uint32_t lpsc_sol_brg_dbg_ctrl5;
    uint32_t lpsc_se_m3_3x1_dlock;
    uint32_t lpsc_se_m3_3x1_priority;
    uint32_t lpsc_se_dma_3x1_dlock;
    uint32_t lpsc_se_dma_3x1_priority;
    uint32_t lpsc_se_sec_4x6_dlock;
    uint32_t lpsc_se_sec_4x6_priority;
    uint32_t lpsc_se_sec_1x3_dlock;
    uint32_t lpsc_se_sec_1x3_priority;
    uint32_t lpsc_se_sec_1x6_dlock;
    uint32_t lpsc_se_sec_1x6_priority;
    uint32_t lpsc_lp_sol_2x1_dlock;
    uint32_t lpsc_lp_sol_2x1_priority;
    uint32_t lpsc_addr_extend0;
    uint32_t lpsc_addr_extend1;
    uint32_t lpsc_adc_ctrl;
    uint32_t lpsc_sram_ini;
    uint32_t lpsc_emp10_err;
    uint32_t lpsc_timer_div;
    uint32_t lpsc_wdg_div;
    uint32_t lpsc_trng_tst_fro_iddq;
    uint32_t lpsc_trng_tst_fro_ctrl_en;
    uint32_t lpsc_trng_tst_fro_select;
    uint32_t lpsc_trng_tst_fro_enable;
    uint32_t lpsc_trng_tst_delay;
    uint32_t lpsc_trng_sp_ram_tmod;
    uint32_t lpsc_trng_mem_power_mode;
    uint32_t lpsc_trng_fsm_state;
    uint32_t lpsc_trng_pproc_state;
    uint32_t lpsc_m3_brg_dbg_ctrl0;
    uint32_t lpsc_m3_brg_dbg_ctrl1;
    uint32_t lpsc_m3_brg_dbg_ctrl2;
    uint32_t lpsc_speed_cnt_cfg;
    uint32_t m3_speed_cnt_match_cfg;
    uint32_t storage_dma_speed_cnt_match_cfg;
    uint32_t dmac_speed_cnt_match_cfg;
    uint32_t m3_speed_cnt_awmatch_inc_cnt;
    uint32_t m3_speed_cnt_rmatch_inc_cnt;
    uint32_t m3_speed_cnt_awcmd_inc_cnt;
    uint32_t m3_speed_cnt_rcmd_inc_cnt;
    uint32_t storage_dma_speed_cnt_awmatch_inc_cnt;
    uint32_t storage_dma_speed_cnt_rmatch_inc_cnt;
    uint32_t storage_dma_speed_cnt_awcmd_inc_cnt;
    uint32_t storage_dma_speed_cnt_rcmd_inc_cnt;
    uint32_t dmac_speed_cnt_awmatch_inc_cnt;
    uint32_t dmac_speed_cnt_rmatch_inc_cnt;
    uint32_t dmac_speed_cnt_awcmd_inc_cnt;
    uint32_t dmac_speed_cnt_rcmd_inc_cnt;
    uint32_t m3_speed_cnt_wdata_cnt_h;
    uint32_t m3_speed_cnt_wdata_cnt_l;
    uint32_t m3_speed_cnt_rdata_cnt_h;
    uint32_t m3_speed_cnt_rdata_cnt_l;
    uint32_t storage_dma_speed_cnt_wdata_cnt_h;
    uint32_t storage_dma_speed_cnt_wdata_cnt_l;
    uint32_t storage_dma_speed_cnt_rdata_cnt_h;
    uint32_t storage_dma_speed_cnt_rdata_cnt_l;
    uint32_t dmac_speed_cnt_wdata_cnt_h;
    uint32_t dmac_speed_cnt_wdata_cnt_l;
    uint32_t dmac_speed_cnt_rdata_cnt_h;
    uint32_t dmac_speed_cnt_rdata_cnt_l;
    uint32_t lpsc_hpm_ctrl;
    uint32_t lpsc_hpm_status;
    uint32_t lpsc_djtag_mstr;
    uint32_t lpsc_ecc_int_raw;
    uint32_t lpsc_ecc_int_mask;
    uint32_t lpsc_ecc_inst;
    uint32_t lpsc_jlc_ram_ini;
    uint32_t lpsc_m3_boot_addr;
    uint32_t lpsc_iomux_ctrl;
    uint32_t lpsc_clken_ctrl2;
    uint32_t lpsc_clkdis_ctrl2;
    uint32_t lpsc_clksta_ctrl2;
    uint32_t lpsc_i2c0_debug;
    uint32_t lpsc_i2c1_debug;
    uint32_t lpsc_i2c2_debug;
    uint32_t lpsc_i2c3_debug;
    uint32_t lpsc_i2c4_debug;
    uint32_t lpsc_i2c5_debug;
    uint32_t lpsc_i2c6_debug;
    uint32_t lpsc_i2c7_debug;
    uint32_t lpsc_i2c8_debug;
    uint32_t lpsc_i2c9_debug;
    uint32_t lpsc_i2c10_debug;
    uint32_t lpsc_i2c11_debug;
    uint32_t lpsc_i2c12_debug;
    uint32_t lpsc_i2c13_debug;
    uint32_t lpsc_i2c14_debug;
    uint32_t lpsc_i2c15_debug;
    uint32_t lpsc_latency_ctrl;
    uint32_t lpsc_hard_rr_ctrl;
    uint32_t lp_sc_latency_sts_0;
    uint32_t lp_sc_latency_sts_1;
    uint32_t lp_sc_latency_sts_2;
    uint32_t lpsc_emmc_dll_st;
    uint32_t lpsc_eco_nonuse0;
    uint32_t lpsc_eco_nonuse1;
    uint32_t lpsc_eco_nonuse2;
    uint32_t lpsc_eco_nonuse3;
    uint32_t lpsc_eco_nonuse4;
    uint32_t lpsc_eco_nonuse5;
    uint32_t lpsc_pad_int_level;
    uint32_t lpsc_pad_int_mask;
    uint32_t lpsc_sram_wr_back;
    uint32_t lpsc_rst_fix;
} lp_subsys_regs;

typedef struct {
    SysBusDevice parent_obj;
    MemoryRegion iomem;
    lp_subsys_regs regs;
} lp_subsys_state;

static const VMStateDescription vmstate_lp_subsys = {
    .name = TYPE_LP_SUBSYS,
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_END_OF_LIST()
    }
};

static void lp_subsys_reset(DeviceState *d)
{
}

static uint64_t lp_subsys_read(void *opaque, hwaddr offset, unsigned size)
{
    lp_subsys_state *s = (lp_subsys_state *)opaque;
    lp_subsys_regs *regs = &s->regs;
    switch (offset) {
        case LPSC_RESET_ST2:
            return regs->lpsc_reset_st2;
        default:
            break;
    }
    return 0;
}

static void lp_subsys_write(void *opaque, hwaddr offset, uint64_t val, unsigned size)
{
    lp_subsys_state *s = (lp_subsys_state *)opaque;
    lp_subsys_regs *regs = &s->regs;
    switch (offset) {
        case LPSC_SRST_REQ2:
            regs->lpsc_srst_req2=val;
            regs->lpsc_reset_st2 |= LPSC_TRNG_BIT;
            break;
        case LPSC_RESET_DREQ2:
            regs->lpsc_reset_dreq2=val;
            regs->lpsc_reset_st2 = 0;
            break;
        default:
            break;
    }
}

static const MemoryRegionOps lp_subsys_ops = {
    .read = lp_subsys_read,
    .write = lp_subsys_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
    .valid.min_access_size = 4,
    .valid.max_access_size = 4,
    .impl.max_access_size = 4,
};

static void lp_subsys_init(Object *obj)
{
    SysBusDevice *sd = SYS_BUS_DEVICE(obj);
    lp_subsys_state *s = LP_SUBSYS(obj);

    memory_region_init_io(&s->iomem, obj, &lp_subsys_ops, s, "lp_subsys.trng", LP_SUBSYS_REGION_SIZE);
    sysbus_init_mmio(sd, &s->iomem);
}

static void lp_subsys_realize(DeviceState *d, Error **errp)
{
}

static void lp_subsys_finalize(Object *obj)
{
}

static Property lp_subsys_properties[] = {
    DEFINE_PROP_END_OF_LIST(),
};

static void lp_subsys_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);

    dc->realize = lp_subsys_realize;
    dc->reset = lp_subsys_reset;
    dc->vmsd = &vmstate_lp_subsys;
    device_class_set_props(dc, lp_subsys_properties);
}

static const TypeInfo lp_subsys_info = {
    .name           = TYPE_LP_SUBSYS,
    .parent         = TYPE_SYS_BUS_DEVICE,
    .instance_size  = sizeof(lp_subsys_state),
    .instance_init  = lp_subsys_init,
    .instance_finalize = lp_subsys_finalize,
    .class_init     = lp_subsys_class_init,
};

static void lp_subsys_register_types(void)
{
    type_register_static(&lp_subsys_info);
}

type_init(lp_subsys_register_types)
